{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "dbe878b3",
   "metadata": {},
   "source": [
    "## 回顾\n",
    "\n",
    "我们刚刚介绍了状态模式和状态更新reducer。<br/>\n",
    "通常，所有图形节点都与单个模式进行通信。<br/>\n",
    "\n",
    "此外，这个单个模式包含图形的输入和输出键/通道。<br/>\n",
    "\n",
    "## 目标\n",
    "\n",
    "但是，在某些情况下，我们可能希望对此有更多的控制：<br/>\n",
    "- 内部节点可能会传递图形的输入/输出中不需要的信息。\n",
    "- 我们可能还想为图使用不同的输入/输出模式。例如，输出可能只包含一个相关的输出键。\n",
    "\n",
    "我们将讨论几种使用多个模式自定义图形的方法。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e2ce1d62",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os, getpass\n",
    "from dotenv import load_dotenv,find_dotenv\n",
    "\n",
    "load_dotenv(find_dotenv())  # 加载 .env 文件中的环境变量\n",
    "\n",
    "api_key = os.environ.get('OPENAI_API_KEY')\n",
    "base_url = os.environ.get('OPENAI_BASE_URL')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "312506f3",
   "metadata": {},
   "source": [
    "## 私有状态\n",
    "首先，让我们介绍在节点之间传递私有状态的情况。<br/>\n",
    "这对于图的中间工作逻辑所需的任何内容都很有用，但与整体图的输入和输出无关。<br/>\n",
    "\n",
    "我们将定义一个OverallState和一个PrivateState。<br/>\n",
    "node_2 使用PrivateState作为输入，但写入OverallState。<br/>\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "72c1d12f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGoAAAFNCAIAAABnnW36AAAQAElEQVR4nOydB3RTR7qAR9Wyim3JvXfA2DiGQOiJaQsEHMDUAAHOS5aFlBdISCHsbshC8tgACyRZWtiUl4QaAlkgsISEHrptMMXghnuTbVm9a38j1mGDpCt5JHMtz3d8dKR758rSp5m5c+fOzM+2WCyI0F7YiIAB0YcF0YcF0YcF0YcF0YcFrr7au1qV3KRVmbRqk8nQOdpALA6Dx2fxBCyhPys0locwYLSv3Vd6XVVyXVV8TSkKYPtJOPBReAImh8tEnQGD3qxVmTUqk7zRoGoxJj4mTEgTxKUKkOu4rK++QndiT71BZ+7e1y8pQxgQzEGdGVmDoTBXcfuywseXmTk1JDjKx6XDXdAHZfPUdw1lBer+YyQp/f2Qd3HjnPzikcaEXsKnpgQ7f5Sz+jRK04Gt1dHd+APHByIvBfLHuR8aa0o0438f4StkOXOIU/oaa/RHvqgZlBUUn9aeCqJzUXxNdf4H6dh54ZIwLmVian1Que79uGrc8+GB4dRv5x1Iq1uzy6SXowR+FHmQ4lxpNFgOfFo9bGpw13EHBEVwn8wOPvhptclIkbcoct/Zf0oFfuyMzADU9cj5uVmnMQ8c56iud5T7WqQGaBV3TXdAn+HiykKNotnoII0jfaf3Sx2793qgiXZ6f4ODBHb1QdaDtnFEoi/qwsT04KtaTA4yoF19hbnK1IHe1jZuB70G+8Nlib29DvQp4np2dCsvMzOztrYWucjOnTvfe+895BliU/iQk+ztta1PKTMyGIjL69AugKqqKqVS6fpx6NatW8hjwOWH0WC2V35td1hVl2gk4a5dPDsPNJW++eabH374oaysLDExccCAAQsWLLhy5crChQth7/jx40eMGPHXv/61qKho7969Fy9ehPwIybKzsydOnAgJ7ty5M3PmzA0bNuzatUsul3M4nNzcXNh+4MAByIZJSUnI3QSG+dSVa0Vi4cO7bOvTqc3QA4E8w/bt2zdv3vz2228PHjz4559/3rhxo5+f3+zZs9etW7d48eKDBw+GhYVBsrVr19bV1S1dupTBYJSUlKxcuTImJqZPnz5cbmsDftu2baNGjerdu3dKSsqcOXPA77vvvos8gw+fCR2aNnfZ1gd9YdChiDwDZJa+fftCLoPnkydP7tevn16vfzjZqlWrVCpVREQEPIf0+/btO3v2LOiz7h00aBDkQdQhgArITzZ32dbHYjH0RtsH4NOrVy/IcStWrIC8M2zYMMhTNpOZzeYdO3acOXOmoqLCuqVbt25teyHTIRpgu4T6ilgahQl5hueee+6tt96SSqXLly+Hag4em5qafpMG3L3yyis5OTmvvvrqyZMnL1++nJaWZt0FZRkeeTysTnaXUCmMfDt9B7ZzH1/EViscXazgwGQys+9RXFwMZ4YtW7ZotVooqg+mgZNpQUEB7Hr88cetW1paWqxPrBfpHTm2RC03gRCbu+zoE7Kg0wZ5Bjg5pKamxsfHJ96jsbHx2LFj6D/ZyopVVmDg/UtGUAlFOD093eYbPnigJ6iv0NrrubJdeCVhHDh7NNd5xOChQ4feeOON06dPQ7Pj1KlT8CQjIwO2R0VFwePRo0dv3ryZkJAAUqB9Ay3B0tLS9evXw9nDXos6MjIyPz8fCrhMJkPuBrIRdFuJ7XSd2tbH5jITUgVwWwN5AGhhxMbGQhtl+PDhH3zwATy++eabsD0uLm7MmDEb7wFtF2ip5OXlwXXIkiVLoB6Ewg5tQ6g3H35D2AV15UsvvQTtG+RuygtUCWlCOJfa3Gu3v6/4qvL84caZb8V4umjQGYvZ8tX7ZUOzg+Pt3Ma02zaOSxMY9ZaiqyrUhbmdo2QwGXDZay+B3VEGkF2HTAiCDJiULoC3eDgBXKLOmjXL5rFwboXSZHPXlClTXn75ZeQZFi1aBOXd5q6AgAB7NSPUEkOGDHl4u9lsuXi4EbIek2m3/FF01n+7oRJuTvYfK7H17ma4KrB5FDRE7LXL4BLVc002tVptMtlurhoMBvjXNnf5+vqy2Tay0S8HGquK1VMXRSP7UOiTNxp3rS0fNTssricfdSVK8lU/7aibviTGT+JoGBBFv4BfIPvp58OPfl0Lt3pRlwG+7E8767LmRzh2hyj1AZGJvpmTg/d+XFl+2yPtGLpRdku996PKzCkhYXHUlYyzgzSqijWHP695YnRg+lB/5L3kHpddOdY07oWI8HinKmgXhgjJmwzfb6oWidlPTQ4Wh3rbXfPGGt3JvQ1qhemZP0CZdXbYmGsD1EwGy43z8twTzdHJ/IRegsgkX45P5xjTZw+91gwFqzRfVVGo7jNM3GuIa2WrncMjS66rinKVZQUq+KEkYdyAYI44hOvkqKRHjlppktXrZfWGpjo9FKm4FEFSb2F8xwyP/A01pdqmWj3cFJY16LVqN/ewQmcMeqDfxV3wBMyAIK5/MCcwjOvM+cEBjI7sOHMV6O+DK+758+cjukJG1mNB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFBx2kxWVlZZrMZPph1trpIJIKXDAbj0KFDiGbQMfeFh4dfunSJxbo/Q84qsV+/foh+0HE+5Jw5c8Ri8YNb/P39586di+gHHfUNGTKke/fuD25JSkoaMGAAoh80nY07c+ZMyHHW5/AE8iOiJTTVN3To0LbV+pKTkwcPHoxoCX3nglszIG1rPSuunXkNOktDlc5i7oi2TkJ439SEofAkJjijqkiDPA+DyQiJ8mFzXVizy9l2X+l11eVjzaoWoyCAzUDeuSiYBVngC/JF7P6jJbHOLfvjlL5/fVXXXK8fmh3m/BITnZcWqeHMvtrgSJ8Rz4ZQJqau++5cUdTe1Y6eG9kV3AH+QZzR86IqCtUl+dSrx1Hryzspe2JMMJvTuRcccQk2h9F/bEjOT82UKamlSKt0YXFdLm5CaJyvtEZHmYxCn1Zl8uGzXDoZeQccLoPDtbtYeBsUDRezp9a+7hxQfn3S34cF0YcF0YcF0YcF0YcF0YcF0YcF0YcF0YcF0YcF0YcFTbuhVq9Z8YcFsxEeCqViyRsvDhvRt7S0GHkGr+3FK7h984Xfz2iQ1iNP4rX6vvhyy6iRT7+26B3kyWBG7q/73l3+JpfLffLJER9++J5Wp01LfWzhwsXdkntY9549e/LL/996t6xELJYkJXWHrxcYGITuxYp4///+mJNzMTGx26SJ05nMX39Xo9H46bZPzl84I5XWp6f3yZ40o19f6hEHLy5YHBMTd+1aLvIk7s99HA4n/3reiRM/frp1x+FDZ+CX/3D1/fCll69c+PPyN0aPztqz+8iypSsrK8s/+fsa6641a1dUVVWs+9vWvyxfffv2zUuXz7W94foNq77bt3PK5Jk7th8cPOipZX9c/Msvpyg/BrhDno9K5n594Eur1S55/U9hYeFsNnvEiDHFxYUGgwF2/eOzjZlPjZycPcPfzz89vffCBYtPnDxWUlIklTYcP/HjzBnzenTvKZEELlywiM26XyzgrY7+eGj2rOezxmf7ifzGj5v01JMjvvp6G6IH7tcHPzX88r6+92+PCAStgUVVqtbIsaWlRT16pLaltJbo23duVldXwpO4+ETrdvgBkv9T2AsLC0D9E/0Gth2VkdEXTgv2AtV0MO6v+0CfzapaqVTqdDofn18XOefzW5eJh1qvRd4aRYj3wK62ZEpla2TmF1+e95t3a2qSCgQdHX35YTqu2WwNUaTV/jrcQq1uzUFw6vATtQ6mgvNM2662ZIFBwfC45PU/RkREPfhuwcGhiAZ0nD6oB7t3S7lx4xqaen/LjZvX4DExIZl9LwjTrVvXrcUZ6ruc3EvhYa2hZSPCo+A8Dtm5d0Zf61GNjVJ4q44M8emADm33TZgw9dTpn/d+txOuB67kXNy0ad2AAUOio2PBVEpK2mefb6qqroQCvuL9d6wxjAGhUDh3znxo69y8mQ9a4Qzz2pIFH3+y2vE/MpvNuXmX4a+4+A5qbULfgOc3b11H7qZDr3nHjM5qaKjfuetLaK+EhYb37TvghRfux2xb9s7KDRtWwXUCnCjGPT0xaviYvLzL1l0zn52XkJD81Tf/uHz5vL9/QGrP9MX3GsMO0Ov1r72+oO3lh6v/gu41Zb78/FvkViiGCKkVph0flk9bEo+6HrvXlD77Zgxf5CiGC+lxwaKz6svPz3tn2SJ7e3fuONQxzZrOqq9Xr4ytW7fb29thTcJOXHitLZtHC6n7sCD6sCD6sCD6sCD6sCD6sCD6sCD6sCD6sKDQx+EyzCb6xgD1KEaDmUM1I4Oiu5Tjw2SyGFpNl5ufAD11XB8mZfBm6t7m4CifsusK1MUoL1DCF6dMRq1vwNOB1041KWVG1GVQNBvyTzf1H0sdVtmpCam1d7U/76pPeSIgNJ4vEnvz2QbE1ZZqCi7Khk8PcSZwtLPTofVa8+UfmyvvqOsrqSfKdV5Con2iu/EfHynm8py6iUaCa2NB2n1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1YEH1Y0HFW0fTp04uL/2udb/iQCQkJe/bsQTSDjsteT5061cfnvyaD8ni8WbNmIfpBR31TpkyJjo5+cAu8nDhxIqIfNF10fdq0aW2rk3K5XHiJaAlN9UFei4yMtD6PjY3Nzs5GtISm+phMJpxAoAakc9ZDNJ/PaxW3e/duRFdcm01ecUfd4NWzyYOjWmeT9x3l1tnkdWXaYzvqU/oHhMX7isTeHCNa0WyoKdXcvigbMSMkNNYdaxmoFabd6yp+NzdKFNBVLlHkTYZjX1dNfz2Gx8dex+XM99LUQeKu4w7wk3B6DhSf2S+lTEmtr7JQHdtDiLoYMT2E8MUpk1Ho02nMJoPF1+HK2V4JX8TSaUwGHcXqUxT6TEYLk9XlApNbYXOYBj3FiYF0WGFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFB9GFBU32r16woKrq9ZfPXqL0olIqPPv7w2rUcubwlObnHhGemjhg+Grkbr819y5e/WVVd8fJLS4RC0ZF/HVj5/rLgoJD09N7IrXinvry8Kzm5lz756LPU1HR42Sst4+zZE6fPHO8E+ugQmxw0ffHZnsjI+yM92Gx2aGi4RkPde+wq3hmbHOzHxsaDNevL8vK7d++WtEWcdiPeH5vcbDav+dvKsLCIsWOeQe7Gy2OTQ52w9J1Xm5ubPlq/rS3mrxvx5tjkNbXVby/9X/g8a1dvstawbsdrY5PDrwLuDxze5wAACJdJREFUIO+vW7vlN4Mt3YjXxiaHcxGcQD5Yuc5z7pC3xibPz8+DlGNGZ5XeLbYGKYe/WwU3kLvxztjktwpao7hv3rLhwY3x8YmfbduF3AqJTW4XEpvc45DY5Fh04tjk27cfsLeXxCanRiQUoUcNqfuwIPqwIPqwIPqwIPqwIPqwIPqwIPqwoNDHpOmMyw6C8utT7OcJWAa9mXJ8vvdh1Fv0OjN8fcfJnAiuHeFTV6ZBXYzau5rQGOopgdT6eg8XXzrSYDZ1oQxoNFgu/FCfkRlAmZJaX0IvQUQC7/A/KuVNBtQFaJEa/vV5ZXR3fkIadbeNs9Oh807KzuyXCv3ZAjGbgTpompb53mdjMjro31mQRdVsVLYYh04KeuxJ6qyHXJ2ML2swqOXGDpu+f+BAa49eVlYW6hDgZ+L7sQOCXZjv7Vq7D97apXfHhMFvhluUkUm+iK6QZjMWRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WRB8WdAzxOW7cuJqamt9sjIiIOHjwIKIZdJzuDPqYDzF27FhEP2gaXDsmJubBLXFxcdOnT0f0g476QkJCRo4c+eCWYcOGBQV5ZO1WTGi6VsHkyZMhx1mfQ06cOnUqoiU01RcaGpqZmWl9PmrUKMiPiJbQd6WMadOmQQaErAdVIaIrbmi4qFqMRVeVLY1GjcKkVZl0Ore1hOrr6uExJNRtWc/Hh8ETsPgill8gO+kxocAft9nbfn0mgyXnuOxOrkLeaAgIF7B9OCwui81hsdj0zdEmo9loMJkMJqPaIKtT+QVyU/oJHxsawOK0c75/O/XdyVGe3tfAEXDF4X6iED7qnMjr1bIauUGlHzopuFuf9oRwdlmfTmM++Glti8wUliThi6lXOqE/qiZNXVGzv4T1zPxwjo9r2dA1ffIm496PqwQSYUiSUwtNdCLAoFammvRSpJ/EhQrRBX115drvN1YHJ0nEkY9+zVVP0FSpaChpyn4pMjjK2WXuna3m4fR6YGtNWPcgb3UHSKJE8AX/ublaJTc5eYhT+ox6876/V/uFi/zCOmg95EeFf6hAFC7av7HKZHSqUDql7/zhZguLHZIgRl0A+JomC/vCkSZnElPrU7WYbp5viUil6WWTJ4hMDb5xTg71FWVKan0nv2uQxPizWB20kBQdYHGYARGi0983Uqak0KdVmStuqwOj/REtkbXULflT/+u3TiF3ExgTUHZTDdegjpNR6Cu6qoBTLaMrZT0rTDYDrkRLrispkjneXZin8g2g7wpcHgW+eFEeRWBBiha2tEqXOMhTV2ZyReM/D6+7W37NYND16DZoVObzQYGt4bBOn9t1/PRXf5j38Rc73mqQloWHJQ8b8lyfx+7HN829dvTIT1u0WmXPHkOfHDgDeQxBoG/pBYrqz1HuMxosbA7cpfFIyTWZTJs+Wwjupk5YtuSVHTwfwUdb/6dZVotaY2pxNVr5vkNrZmT/ec2KCyndBu/a9xeFsrUlUVNXtP3bPz/RJ+vtRd/27vW7fYfWIo8BZ0sGE5nNjtI40qdoNoI+5BlKy/IgZz07eXn35P4ioWTC06/5cH3PnN+N7kUJhPw4duTC2Og0ePnE41kmk7G6phCe/3JhryQgYsRT83x9Rd2SnujXZzzyJND/pmx2tOSoIztwJMNj+u6WX+VyeInxfe5/DiYzPjajqOQKuhdnEB6jI3tad/F8WruSNNrWcIENjeWhoQltbxIdmYI8CZxAIA85SEBR91k8tmCuRqvUG7TQ7Hhwo5/o3u20e/raIjU+WHeo1XKh4NeLHy7H46c1x4XXkT5fERuudpFnEAkDob6bN/O/AtYxWRTLTEOZBeltL3U6pwJ9thujztz+QGNwpEHrbN+Dq4SHJWl1KnFAWKAk0rpF2lTpJ6S4mQvpbxeeN5vN1vjHt+6cRZ7EoDEK/Bzpc1S18YUsvdZk1HvEYPek/t2S+u/e/z5cOShVzdBYWb9p7pWrhx0flZ46QqFsPHT0E6gfC4svnbu0D3kM+OJGg5nHb3eYOwaCjkOFVCOOaM99AEpeeG792Qt7vtq1rKwiPyQorv/jEwb2m+T4kJ7dB48f/cq5i9+dPPuNRBwBLRto/SDPjHJS1KuDo3iO16im6G3OPS4ryNWGpwSjrkfNzfqe/Xwdr39N0S5JyhA216hMek/VgLTFqDU116qTe1N0rVM0XERidmwKX1reEpoksZkAGrTvrhpt+xMY9WwW12bmjwhNfvGFzch9/On9kRZkuxiZzSYm00b9FROVOn/uR8gOjeWyhDSB49MucuZWEdxd276qLHlwNNwFt5mgqbna5na4LOXxbFeaLBbH38+dFYK9zwDoDToux8atH7g0vN/MfAjIeoXnKmYvjYXcgxzi1J22k3sbKov1EWmhDIb391yBkMqrtfE9eUMmUA+Jc+qabFBWIJtllt6VoS5AQ3Ezj2cZ8LTEmcRO6eNwmRNfjNS1qOV1nm3lP3LktSqDSjNhYaSTfSUu3CbXKE37N9f4iPhw6wN5I41lMnA3cUEET+BsR4lrgzTg7ufhL2qVCkZotyAG03vqQYvZUlPQECBhjH4ulMV24Xu1Z4TV5aPN18/LQxKD+BKvGCIk1TSUNqUNEvUd6fKN7HYOUJM1GHKOyxprjFx/vkDsy+ayUGcDLmnVTRptizo4kt07M6B9YVywRpdCb/7dW+o7OaqmGj1iMlgcFoPNYtI4NB501ViMrcMjobQGRXC79xEk9MIaduK2WUVKmRGyZIvU4MzN+UcDAwn82P5BrfGChAHumY1Gx0lZnQgyJRALog8Log8Log8Log8Log+LfwMAAP//Tq8nTAAAAAZJREFUAwCBaya3Md47+gAAAABJRU5ErkJggg==",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from typing_extensions import TypedDict\n",
    "from IPython.display import Image, display\n",
    "from langgraph.graph import StateGraph, START, END\n",
    "\n",
    "class OverallState(TypedDict):\n",
    "    foo: int\n",
    "\n",
    "class PrivateState(TypedDict):\n",
    "    baz: int\n",
    "\n",
    "def node_1(state: OverallState) -> PrivateState:\n",
    "    print(\"---Node 1---\")\n",
    "    return {\"baz\": state['foo'] + 1}\n",
    "\n",
    "def node_2(state: PrivateState) -> OverallState:\n",
    "    print(\"---Node 2---\")\n",
    "    return {\"foo\": state['baz'] + 1}\n",
    "\n",
    "#建立公有状态的图\n",
    "builder = StateGraph(OverallState)\n",
    "builder.add_node(\"node_1\", node_1)\n",
    "builder.add_node(\"node_2\", node_2)\n",
    "\n",
    "\n",
    "builder.add_edge(START, \"node_1\")\n",
    "builder.add_edge(\"node_1\", \"node_2\")\n",
    "builder.add_edge(\"node_2\", END)\n",
    "\n",
    "\n",
    "graph = builder.compile()\n",
    "\n",
    "\n",
    "display(Image(graph.get_graph().draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "152fb9d3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---Node 1---\n",
      "---Node 2---\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'foo': 4}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph.invoke({\"foo\" : 2})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "fc13afab",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "class OverallState(TypedDict):\n",
    "    question: str\n",
    "    answer: str\n",
    "    notes: str\n",
    "\n",
    "def thinking_node(state: OverallState):\n",
    "    return {\"answer\": \"再见\", \"notes\": \"... 他的名字叫Ronnie\"}\n",
    "\n",
    "def answer_node(state: OverallState):\n",
    "    return {\"answer\": \"再见Ronnie\"}\n",
    "\n",
    "graph = StateGraph(OverallState)\n",
    "graph.add_node(\"answer_node\", answer_node)\n",
    "graph.add_node(\"thinking_node\", thinking_node)\n",
    "graph.add_edge(START, \"thinking_node\")\n",
    "graph.add_edge(\"thinking_node\", \"answer_node\")\n",
    "graph.add_edge(\"answer_node\", END)\n",
    "\n",
    "graph = graph.compile()\n",
    "\n",
    "\n",
    "display(Image(graph.get_graph().draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4712e14c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'question': '你好', 'answer': '再见Ronnie', 'notes': '... 他的名字叫Ronnie'}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph.invoke({\"question\":\"你好\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "570018c1",
   "metadata": {},
   "source": [
    "现在，让我们在途中使用特定的“输入”和“输出”模式。<br/>\n",
    "在这里，“输入”/“输出”模式图表的输入和输出上允许的键执行过滤。<br/>\n",
    "此外，我们可以使用类型提示“state： inputState”来制定每个节点的输入模式。<br/>\n",
    "\n",
    "当图表使用多个模式时，这一点很重要。<br/>\n",
    "我们使用下面的类型提示来例如显示“answer_node”的输出将被过滤到“OutputState”。<br/>\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e9791fed",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "{'answer': '再见Ronnie'}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class InputState(TypedDict):\n",
    "    question: str\n",
    "\n",
    "class OutputState(TypedDict):\n",
    "    answer: str\n",
    "\n",
    "class OverallState(TypedDict):\n",
    "    question: str\n",
    "    answer: str\n",
    "    notes: str\n",
    "\n",
    "def thinking_node(state: InputState):\n",
    "    return {\"answer\": \"再见\", \"notes\": \"... 他的名字叫Ronnie\"}\n",
    "\n",
    "def answer_node(state: OverallState) -> OutputState:\n",
    "    return {\"answer\": \"再见Ronnie\"}\n",
    "\n",
    "graph = StateGraph(OverallState, input=InputState, output=OutputState)\n",
    "graph.add_node(\"answer_node\", answer_node)\n",
    "graph.add_node(\"thinking_node\", thinking_node)\n",
    "graph.add_edge(START, \"thinking_node\")\n",
    "graph.add_edge(\"thinking_node\", \"answer_node\")\n",
    "graph.add_edge(\"answer_node\", END)\n",
    "\n",
    "graph = graph.compile()\n",
    "\n",
    "# View\n",
    "display(Image(graph.get_graph().draw_mermaid_png()))\n",
    "\n",
    "graph.invoke({\"question\":\"hi\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b569d527",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.10",
   "language": "python",
   "name": "python310"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
